package cn.ultrarisk.scadmin.manager.biz.stat.dao;

import cn.ultrarisk.mybatis.extension.domain.Entity;
import cn.ultrarisk.mybatis.extension.query.Column;
import cn.ultrarisk.mybatis.extension.query.Query;
import cn.ultrarisk.scadmin.manager.biz.solr.dao.SolrNodeDAO;
import cn.ultrarisk.scadmin.manager.biz.stat.context.StatType;
import cn.ultrarisk.scadmin.manager.biz.stat.dto.HighchartResult;
import cn.ultrarisk.scadmin.manager.biz.stat.dto.HighchartSerie;
import cn.ultrarisk.scadmin.manager.biz.stat.dto.StatisticsFilter;
import cn.ultrarisk.scadmin.manager.biz.stat.entity.SolrNodeStat;
import cn.ultrarisk.scadmin.manager.biz.stat.entity.SolrReplicaStat;
import cn.ultrarisk.scadmin.manager.exception.BizCheckedException;
import cn.ultrarisk.scadmin.manager.support.BaseDAO;
import cn.ultrarisk.scadmin.manager.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * solr节点统计数据操作类
 *
 * @author sevendlong(lin23871@163.com)
 * @date 2014/3/28
 * @since V1.0
 */
@Repository
public class SolrNodeStatDAO extends BaseDAO<SolrNodeStat, Long> {
    @Autowired
    private SolrNodeDAO solrNodeDAO;

    /**
     * 构造器
     */
    public SolrNodeStatDAO() {
        super(SolrNodeStat.class, SolrNodeStat.COLUMN_PROPERTY_MAP);
    }

    public List<SolrNodeStat> buildStat(long startTime, long endTime) {
        Query query = Query.gteQuery(SolrNodeStat.START_TIME, startTime).lt(SolrNodeStat.START_TIME, endTime);
        return sqlSessionTemplate.selectList(this.entityName + ".buildStat", query.toMap(tableName));
    }

    public HighchartResult getAvgMemusageStat(StatisticsFilter filter) {
        return getStat(filter, Column.Fx.AVG, SolrNodeStat.AVG_MEMUSAGE);
    }

    public HighchartResult getMaxMemusageStat(StatisticsFilter filter) {
        return getStat(filter, Column.Fx.MAX, SolrNodeStat.MAX_MEMUSAGE);
    }

    public HighchartResult getAvgLoadStat(StatisticsFilter filter) {
        return getStat(filter, Column.Fx.AVG, SolrNodeStat.AVG_LOAD);
    }

    public HighchartResult getMaxLoadStat(StatisticsFilter filter) {
        return getStat(filter, Column.Fx.MAX, SolrNodeStat.MAX_LOAD);
    }

    public HighchartResult getStat(StatisticsFilter filter, Column.Fx fx, String column) {
        List<String> groupKeys = new ArrayList<String>();
        groupKeys.add(SolrReplicaStat.NODE_ID);
        Long starTime = DateUtil.getDayBeginTime(filter.getStartTime());
        Long endTime = DateUtil.getDayEndTime(filter.getEndTime());
        List<Object> categories = new ArrayList<Object>();
        if (filter.getStatType() == StatType.HOUR) {
            groupKeys.add("FROM_UNIXTIME(start_time / 1000, '%Y%m%d%H')");
            for (Long time = starTime; time <= endTime; time = DateUtil.addHour(time, 1)) {
                categories.add(time);
            }
        } else if (filter.getStatType() == StatType.DAY) {
            groupKeys.add("FROM_UNIXTIME(start_time / 1000, '%Y%m%d')");
            for (Long time = starTime; time <= endTime; time = DateUtil.addDay(time, 1)) {
                categories.add(time);
            }
        } else if (filter.getStatType() == StatType.WEEK) {
            groupKeys.add("FROM_UNIXTIME(start_time / 1000, '%Y%u')");
            for (Long time = starTime; time <= endTime; time = DateUtil.addMonth(time, 1)) {
                categories.add(time);
            }
        } else if (filter.getStatType() == StatType.MONTH) {
            groupKeys.add("FROM_UNIXTIME(start_time / 1000, '%Y%m')");
            for (Long time = starTime; time <= endTime; time = DateUtil.addMonth(time, 1)) {
                categories.add(time);
            }
        } else {
            throw new BizCheckedException("filter is error");
        }
        Query query = new Query();
        query.eq(SolrNodeStat.NODE_ID, filter.getNodeId());
        query.gte(SolrNodeStat.START_TIME, starTime);
        query.lt(SolrNodeStat.START_TIME, endTime);
        query.setGroups(groupKeys);

        String[] tableColumns = new String[]{
                SolrReplicaStat.NODE_ID,
                Column.min(SolrReplicaStat.START_TIME),
                Column.fx(fx, column)
        };
        List<Entity> stats = findEntityList(query, tableColumns);

        List<Integer> nodeIds = new ArrayList<Integer>();
        for (Map<String, Object> stat : stats) {
            nodeIds.add(Integer.parseInt(stat.get(SolrReplicaStat.NODE_ID).toString()));
        }
        Map<Integer, String> nameMap = solrNodeDAO.getNameMap(nodeIds);

        if (nameMap != null) {
            Map<String, HighchartSerie> series = new HashMap<String, HighchartSerie>();
            for (Map<String, Object> stat : stats) {
                Long startTime = Long.parseLong(stat.get(SolrReplicaStat.START_TIME).toString());
                String name = nameMap.get(Integer.parseInt(stat.get(SolrReplicaStat.NODE_ID).toString()));
                HighchartSerie serie = series.get(name);
                if (serie == null) {
                    serie = new HighchartSerie();
                }
                for (Object category : categories) {
                    if (category.equals(startTime)) {
                        serie.addData(category, stat.get(column));
                    }
                }
                series.put(name, serie);
            }
            for (String name : series.keySet()) {
                HighchartSerie serie = series.get(name);
                serie.setName(name);
                for (Object category : categories) {
                    if (!serie.getData().containsKey(category)) {
                        serie.addData(category, 0);
                    }
                }
            }
            return new HighchartResult(categories, new ArrayList<HighchartSerie>(series.values()));
        }
        return null;
    }
}
